package com.iwhalecloud.bss.kite.cucc.web.service.accept.handler.module;

import com.google.common.collect.Lists;
import com.iwhalecloud.bss.kite.client.vo.scene.ModuleVO;
import com.iwhalecloud.bss.kite.common.util.KiteListUtils;
import com.iwhalecloud.bss.kite.common.util.KiteMapUtils;
import com.iwhalecloud.bss.kite.common.util.KiteStringUtils;
import com.iwhalecloud.bss.kite.cucc.client.vo.scene.OptionalAdditionalOfferModuleVO;
import com.iwhalecloud.bss.kite.cucc.client.vo.scene.SceneNewOfferSeneVO;
import com.iwhalecloud.bss.kite.cucc.client.vo.scene.SceneProductModuleVO;
import com.iwhalecloud.bss.kite.cucc.common.constant.LocalKeyConsts;
import com.iwhalecloud.bss.kite.cucc.common.util.DateFormatUtils;
import com.iwhalecloud.bss.kite.cucc.service.pos.handler.CuccPosServiceUtils;
import com.iwhalecloud.bss.kite.cucc.service.util.ProdCateUtil;
import com.iwhalecloud.bss.kite.dataservice.cache.DcPublicCache;
import com.iwhalecloud.bss.kite.dataservice.cache.OfferCache;
import com.iwhalecloud.bss.kite.dataservice.cache.ProdFeeCache;
import com.iwhalecloud.bss.kite.dataservice.entity.DcPublic;
import com.iwhalecloud.bss.kite.dataservice.entity.spec.Offer;
import com.iwhalecloud.bss.kite.dataservice.entity.spec.OfferRelInfo;
import com.iwhalecloud.bss.kite.manager.api.IQuerySceneInstService;
import com.iwhalecloud.bss.kite.manager.enums.ActionType;
import com.iwhalecloud.bss.kite.manager.inst.KiteAttr;
import com.iwhalecloud.bss.kite.manager.inst.KiteAttrValue;
import com.iwhalecloud.bss.kite.manager.inst.KiteOfferInst;
import com.iwhalecloud.bss.kite.manager.inst.KiteSceneInst;
import com.iwhalecloud.bss.kite.web.context.KiteWebContext;
import com.iwhalecloud.bss.kite.web.service.accept.bo.AcceptContext;
import com.iwhalecloud.bss.kite.web.service.accept.bo.SceneModule;
import com.iwhalecloud.bss.kite.web.service.accept.handler.module.AbstractModuleHandler;
import com.ztesoft.bss.base.staticdata.CoreDataOffer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;
import java.util.Optional;
import java.util.Collections;
import java.util.Comparator;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class ShutdownAdditionalOfferModuleHandler extends AbstractModuleHandler {

    @Autowired
    IQuerySceneInstService querySceneInstService;

    @Override
    public List<? extends ModuleVO> execute(AcceptContext context, SceneModule sceneModule) {

        List<OptionalAdditionalOfferModuleVO> additionalOfferModuleVOList = new ArrayList<>();
        String sceneInstId = context.getSceneVo().getSceneInstId();
        if (!isStopOrRecoveryScene(sceneInstId)) {
            return additionalOfferModuleVOList;
        }
        Map<String, OptionalAdditionalOfferModuleVO> additionalOfferModuleVO = getOptionalAdditionalOfferModuleVO(sceneInstId, false);
        SceneProductModuleVO sceneFeeInfoVo = ((SceneNewOfferSeneVO) context.getSceneVo()).getSceneProductModuleVO();
        sceneFeeInfoVo.setAdditionalOffers(additionalOfferModuleVO);
        for (Map.Entry<String, OptionalAdditionalOfferModuleVO> entry : additionalOfferModuleVO.entrySet()) {
            additionalOfferModuleVOList.add(entry.getValue());
        }
        return additionalOfferModuleVOList;
    }

    @Override
    public List<? extends ModuleVO> previewSceneVo(AcceptContext context, SceneModule sceneModule) {

        Map<String, OptionalAdditionalOfferModuleVO> additionalOfferModuleVOMap = new HashMap<>();
        List<OptionalAdditionalOfferModuleVO> additionalOfferModuleVOList = new ArrayList<>();
        //所有的主套餐
        List<KiteOfferInst> offerInsts = Lists.newArrayList();
        String sceneInstId = context.getAcceptRequest().getSceneInstId();
        offerInsts.addAll(querySceneInstService.listMainOfferInsts(sceneInstId));
        offerInsts.addAll(querySceneInstService.listPromotionOfferInsts(sceneInstId));
        KiteSceneInst sceneInst = querySceneInstService.getSceneInst(sceneInstId);
        for (KiteOfferInst kiteOfferInst : offerInsts) {
            List<KiteOfferInst> additionalOfferInsts = querySceneInstService.listAdditionalOfferInstsFromOfferInst(KiteWebContext.getContext().getCustId(), kiteOfferInst.getOfferInstId())
                .stream().filter(additionalOfferInst -> {
                    Map<String, Object> offerMap = Optional.ofNullable(OfferCache.get(additionalOfferInst.getOfferId())).map(Offer::getOfferMap).orElse(null);
                    return LocalKeyConsts.FEE_PAY_TYPE_SHUTDOWN_NUMBER.equals(KiteMapUtils.getString(offerMap, "payType"));
                }).collect(Collectors.toList());
            if (KiteListUtils.isNotEmpty(additionalOfferInsts)) {
                OptionalAdditionalOfferModuleVO additionalOfferModuleVO = new OptionalAdditionalOfferModuleVO();
                DealAdditionalOfferInst(sceneInstId, kiteOfferInst, additionalOfferModuleVO, additionalOfferInsts, true);
                additionalOfferModuleVO.setOfferInstId(kiteOfferInst.getOfferInstId());
                additionalOfferModuleVO.setOfferName(OfferCache.get(kiteOfferInst.getOfferId()).getOfferName());
                additionalOfferModuleVO.setOfferInstId(kiteOfferInst.getOfferInstId());
                additionalOfferModuleVO.setPreviewFlag(true);
                additionalOfferModuleVOMap.put(kiteOfferInst.getOfferInstId(), additionalOfferModuleVO);
                additionalOfferModuleVOList.add(additionalOfferModuleVO);
            }

        }
        SceneProductModuleVO sceneFeeInfoVo = ((SceneNewOfferSeneVO) context.getSceneVo()).getSceneProductModuleVO();
        sceneFeeInfoVo.setAdditionalOffers(additionalOfferModuleVOMap);
        return additionalOfferModuleVOList;
    }

    private boolean isStopOrRecoveryScene(String sceneInstId) {
        String bizType = querySceneInstService.getExtParameterValue(sceneInstId, "bizType");
        KiteAttr stopRatioAttr = querySceneInstService.getCommonAttr(sceneInstId, "STOP_RATIO");
        KiteAttr recoverRatioAttr = querySceneInstService.getCommonAttr(sceneInstId, "RECOVER_RATIO");
        if (Objects.isNull(stopRatioAttr) && Objects.isNull(recoverRatioAttr)) {
            return KiteStringUtils.equalsAny(bizType, "1003", "1004", "1048");
        }
        else {
            // 如果停机属性不存在,那么判断复机类型,否则判断停机类型
            return Objects.isNull(stopRatioAttr) ? KiteStringUtils.equalsAny(recoverRatioAttr.getValue(), "1004", "1048") : "1003".equals(stopRatioAttr.getValue());
        }
    }

    public Map<String, OptionalAdditionalOfferModuleVO> getOptionalAdditionalOfferModuleVO(String sceneInstId, boolean isPrivew) {
        Map<String, OptionalAdditionalOfferModuleVO> additionalOfferModuleVOMap = new HashMap<>();
        // 批量受理当前修改销售品实例标识，存在则说明是批量受理的单个修改场景
        String curOfferInstId = querySceneInstService.getExtParameterValue(sceneInstId, "curOfferInstId");
        // 停开机场景
        String stopRatioAttrValue = querySceneInstService.getCommonAttrValue(sceneInstId, "STOP_RATIO");
        //所有的主套餐
        List<KiteOfferInst> offerInsts = Lists.newArrayList();
        offerInsts.addAll(querySceneInstService.listMainOfferInsts(sceneInstId));
        offerInsts.addAll(querySceneInstService.listPromotionOfferInsts(sceneInstId));
        // 批量受理的单个修改，只处理当前修改的销售品实例
        if (KiteStringUtils.isNotEmpty(curOfferInstId)) {
            offerInsts.removeIf(offerInstDTO -> !KiteStringUtils.isEqual(offerInstDTO.getOfferInstId(),
                curOfferInstId));
        }

        // 五大双线，附加商品不显示停机保号费
        String custId = KiteWebContext.getContext().getCustId();
        String catagoryId = CuccPosServiceUtils.getCateId(sceneInstId, custId);
        String[] doubleLineCateIdArr = ProdCateUtil.getDoubleLineCateIdForArr();
        boolean flag = KiteStringUtils.equalsAny(catagoryId, doubleLineCateIdArr);
        for (KiteOfferInst kiteOfferInst : offerInsts) {
            // 主产品删除了，不加载
            if (KiteStringUtils.isEqual(kiteOfferInst.getActionType().name(), ActionType.D.name())) {
                continue;
            }
            //查询所有的可选包规格
            List<OfferRelInfo> offerRelInfoList = OfferCache.get(kiteOfferInst.getOfferId()).listAllOfferRels().stream().filter(offerRelInfo -> {
                return CoreDataOffer.OFF_0005_12.equals(offerRelInfo.getzOfferType());
            }).collect(Collectors.toList());
            if (KiteListUtils.isEmpty(offerRelInfoList)) {
                continue;
            }
            offerRelInfoList = offerRelInfoList.stream().filter(offerRelInfo -> {
                Map<String, Object> offerMap = Optional.ofNullable(ProdFeeCache.get(offerRelInfo.getzOfferId())).map(Offer::getOfferMap).orElse(null);
                return LocalKeyConsts.FEE_PAY_TYPE_SHUTDOWN_NUMBER.equals(KiteMapUtils.getString(offerMap, "payType"));
            }).collect(Collectors.toList());
            //没有停机保号费，则退出
            if (KiteListUtils.isEmpty(offerRelInfoList)) {
                continue;
            }
            if(flag) {
                // 五大双线附加商品，不显示新增停机保号费按钮
                String thisCateId = Optional.ofNullable(OfferCache.get(kiteOfferInst.getOfferId())).map(Offer::getCateId).orElse(null);
                if(!KiteStringUtils.equalsAny(thisCateId, doubleLineCateIdArr)) {
                    continue;
                }
            }

            OptionalAdditionalOfferModuleVO additionalOfferModuleVO = new OptionalAdditionalOfferModuleVO();
            additionalOfferModuleVO.setOfferName(OfferCache.get(kiteOfferInst.getOfferId()).getOfferName());
            additionalOfferModuleVO.setOfferInstId(kiteOfferInst.getOfferInstId());
            List<KiteOfferInst> additionalOfferInsts = querySceneInstService.listAdditionalOfferInstsFromOfferInst(custId, kiteOfferInst.getOfferInstId());
            // 停开机界面只需要展示停机保号资费信息，其他信息过滤
            additionalOfferInsts = additionalOfferInsts.stream().filter(additionalOfferInst -> {
                Map<String, Object> offerMap = Optional.ofNullable(ProdFeeCache.get(additionalOfferInst.getOfferId())).map(Offer::getOfferMap).orElse(null);
                return LocalKeyConsts.FEE_PAY_TYPE_SHUTDOWN_NUMBER.equals(KiteMapUtils.getString(offerMap, "payType"));
            }).collect(Collectors.toList());
            if (KiteListUtils.isNotEmpty(additionalOfferInsts)) {
                DealAdditionalOfferInst(sceneInstId, kiteOfferInst, additionalOfferModuleVO, additionalOfferInsts, isPrivew);
            }
            else {
                //当前没有停机保号费,且不是普通停机场景,模块不展示
                if (!"1003".equals(stopRatioAttrValue)) {
                    return new HashMap<>();
                }
                additionalOfferModuleVO.setAddButton(true);
            }

            additionalOfferModuleVOMap.put(kiteOfferInst.getOfferInstId(), additionalOfferModuleVO);
        }
        return additionalOfferModuleVOMap;
    }

    private void DealAdditionalOfferInst(String sceneInstId, KiteOfferInst kiteOfferInst, OptionalAdditionalOfferModuleVO additionalOfferModuleVO, List<KiteOfferInst> additionalOfferInsts, boolean isPrivew) {

        //拼装表头
        List<Map> tableColList = new ArrayList();
        //描述字段组装
        List<String> feeDescribeFieldList = new ArrayList();
        //拼装表数据
        List<Map> tableValueList = new ArrayList();
        String catId = kiteOfferInst.getAttrValue("cateId");
        getTableHeader(tableColList, catId, feeDescribeFieldList);
        //先按照生效时间排序
        sortKitePosFeeList(additionalOfferInsts);
        //再按照销售品ID进行排序
        sortOfferList(additionalOfferInsts);
        additionalOfferInsts.forEach(feeOfferInst ->{
            Map tableValue = new HashMap();
            for(Map<String, String> tableCol : tableColList) {
                String key = tableCol.get("dataIndex");
                if (KiteStringUtils.isEqual(key,"ctrl")) {
                    continue;
                }
                if (KiteStringUtils.isEqual(key,"name")) {
                    tableValue.put(key, feeOfferInst.getOfferName());
                }
                else if (KiteStringUtils.isEqual(key,"feeDescribe")) {
                    StringBuffer feeDescribe = new StringBuffer();
                    for (String feeDescribeField :feeDescribeFieldList) {
                        if (!KiteStringUtils.isEqual(feeDescribeField, "name")) {
                            KiteAttr kiteAttr = feeOfferInst.getAttr(feeDescribeField);
                            if (Objects.nonNull(kiteAttr)) {
                                feeDescribe.append(kiteAttr.getCname()).append("=").append(getValue(kiteAttr)).append(";");
                            }
                        }
                    }
                    tableValue.put(key, feeDescribe.toString());
                }
                else if (KiteStringUtils.isEqual(key,"actionType")) {
                    tableValue.put(key, feeOfferInst.getActionType().name());
                }
                else {
                    KiteAttr kiteAttr = feeOfferInst.getAttr(key);
                    tableValue.put(key, getValue(kiteAttr));

                }
            }

            tableValue.put("offerInstId", feeOfferInst.getOfferInstId());
            Map<String, Object> offerMap = ProdFeeCache.get(feeOfferInst.getOfferId()).getOfferMap();
            String payType = KiteMapUtils.getString(offerMap, "payType");
            if (KiteMapUtils.isNotEmpty(offerMap)) {
                tableValue.put("payType", payType);
            }
            if (!isPrivew) {
                ActionType action = feeOfferInst.getActionType();
                if (KiteStringUtils.isEqual(action.name(), ActionType.A.name())) {
                    //资费产品实例为新增状态时，有删除和修改操作
                    tableValue.put("delOfferInst", "true");
                    tableValue.put("modOfferInst", "true");
                }
                else if (KiteStringUtils.isEqual(action.name(), ActionType.C.name())) {
                    //资费产品实例为作废状态时，有撤销操作
                    tableValue.put("revokeOfferInst", "true");
                }
                else {
                    //资费产品实例为不变、修改状态时，有修改操作
                    tableValue.put("modOfferInst", "true");

                    String startDate = getValue (feeOfferInst.getAttr("200000172"));
                    // 未生效的资费，可以作废
//                    if (KiteStringUtils.isNotEmpty(startDate)
//                        && DateFormatUtils.compareDate(DateFormatUtils.getFormatedDateTime(), startDate, DateFormatUtils.DATE_TIME_FORMAT)<0) {
//                        tableValue.put("cancelOfferInst", "true");
//                    }
                    // 生效模式
                    KiteAttr effectiveMode =feeOfferInst.getAttr("200000174");
                    if (Objects.nonNull(effectiveMode) && KiteStringUtils.isEqual(effectiveMode.getValue(), "110006909")) {
                        tableValue.put("200000174", getValue(effectiveMode));
                    }

                    // 失效模式
                    KiteAttr failureMode =feeOfferInst.getAttr("200001735");
                    if (Objects.nonNull(failureMode) && KiteStringUtils.isEqual(failureMode.getValue(), "110006910")) {
                        tableValue.put("200001735", getValue(failureMode));
                    }
                }
            }

            tableValueList.add(tableValue);
        });
        Map tableFeeAttr = new HashMap();
        tableFeeAttr.put("tableCol", tableColList);
        tableFeeAttr.put("tableValue", tableValueList);
        additionalOfferModuleVO.setTableFeeAttr(tableFeeAttr);
    }

    private void getTableHeader(List<Map> tableColList, String catId, List<String> feeDescribeFieldList) {
        List<DcPublic> dcpublicList = DcPublicCache.getByPkey("20210204", "feeTableHead");
        DcPublic collect = getDcpubliBinaryOperator(dcpublicList, catId);
        if (Objects.isNull(collect)) {
            Map col = new HashMap();
            col.put("dataIndex", "name");
            col.put("title", "资费名称");
            tableColList.add(col);
            Map col1 = new HashMap();
            col1.put("dataIndex", "feeDescribe");
            col1.put("title", "资费描述");
            tableColList.add(col1);
            Map col2 = new HashMap();
            col2.put("dataIndex", "200000172");
            col2.put("title", "生效时间");
            tableColList.add(col2);
            Map col3 = new HashMap();
            col3.put("dataIndex", "200000173");
            col3.put("title", "失效时间");
            tableColList.add(col3);
            Map col4 = new HashMap();
            col4.put("dataIndex", "actionType");
            col4.put("title", "修改标记");
            tableColList.add(col4);
            Map col5 = new HashMap();
            col5.put("dataIndex", "ctrl");
            col5.put("title", "操作");
            tableColList.add(col4);
            feeDescribeFieldList.add("name");//协议月租（元）
            feeDescribeFieldList.add("200000169");//协议月租（元）
            feeDescribeFieldList.add("200000170");//首月收取方式
            feeDescribeFieldList.add("200000171");//末月收取方式
        }
        else {
            String codea = collect.getCodea();
            String codeb = collect.getCodeb();
            if (KiteStringUtils.isNotEmpty(codea)) {
                String[] tablecode = codea.split(",");
                for (int i = 0; i < tablecode.length; i++) {
                    String[] tableHead = tablecode[i].split("\\|");
                    if (tableHead.length <2) {
                        continue;
                    }
                    Map col = new HashMap();
                    col.put("dataIndex", tableHead[0]);
                    col.put("title", tableHead[1]);
                    tableColList.add(col);
                }
            }
            if (KiteStringUtils.isNotEmpty(codeb)) {
                String[] describeField = codeb.split(",");
                for (int i = 0; i < describeField.length; i++) {
                    feeDescribeFieldList.add(describeField[i]);
                }
            }
        }
    }

    private DcPublic getDcpubliBinaryOperator(List<DcPublic> dcpublicList, String catId) {
        if (KiteListUtils.isEmpty(dcpublicList)) {
            return null;
        }
        DcPublic result = dcpublicList.stream().filter(dcpublic -> KiteStringUtils.isEqual(dcpublic.getPcode(), catId)).findFirst().orElse(null);
        if (Objects.isNull(result)) {
            result = dcpublicList.stream().filter(dcpublic -> KiteStringUtils.isEqual(dcpublic.getPcode(), "-1")).findFirst().orElse(null);
        }
        return result;
    }

    private String getValue (KiteAttr kiteAttr) {
        if (Objects.nonNull(kiteAttr)) {
            String value = KiteStringUtils.isEmpty(kiteAttr.getValue()) ?
                (KiteStringUtils.isEmpty(kiteAttr.getDefaultValue()) ? "" : kiteAttr.getDefaultValue()) :
                kiteAttr.getValue();
            List<KiteAttrValue> attrValues = kiteAttr.getAttrValues();
            if (KiteListUtils.isNotEmpty(attrValues)) {
                String valueId = value;
                KiteAttrValue kiteAttrValue = attrValues.stream().filter(attrValue -> KiteStringUtils.equals(valueId, attrValue.getAttrValue())).findFirst().orElse(null);
                value = kiteAttrValue.getAttrValueName();
            }
            return value;
        }

        return "";
    }

    // 按照生效时间进行排序
    public static void sortKitePosFeeList(List<KiteOfferInst> fees) {
        Collections.sort(fees, new Comparator<KiteOfferInst>() {

            @Override
            public int compare(KiteOfferInst o1, KiteOfferInst o2) {

                List<KiteAttr> OfferVO1 = o1.listAttrs();
                KiteAttr offerPosAttrO1 = OfferVO1.stream().filter(offerAttr -> KiteStringUtils.isEqual(offerAttr.getFieldName(), "200000172")).findFirst().orElse(new KiteAttr());
                String o1EffDate = offerPosAttrO1.getValue();
                List<KiteAttr> OfferVO2 = o2.listAttrs();
                KiteAttr offerPosAttrO2 = OfferVO2.stream().filter(offerAttr -> KiteStringUtils.isEqual(offerAttr.getFieldName(), "200000172")).findFirst().orElse(new KiteAttr());
                String o2EffDate = offerPosAttrO2.getValue();

                if (KiteStringUtils.isEmpty(o1EffDate)) {
                    o1EffDate = DateFormatUtils.formatDate(DateFormatUtils.DEFAULTPATTERN);
                }
                if (KiteStringUtils.isEmpty(o2EffDate)) {
                    o2EffDate = DateFormatUtils.formatDate(DateFormatUtils.DEFAULTPATTERN);
                }
                return DateFormatUtils.compareDate(o1EffDate, o2EffDate,  DateFormatUtils.DEFAULTPATTERN);
            }
        });
    }

    //根据销售品ID进行排序
    private static void sortOfferList(List<KiteOfferInst> fees) {
        Collections.sort(fees, new Comparator<KiteOfferInst>() {

            @Override
            public int compare(KiteOfferInst o1, KiteOfferInst o2) {
                return o1.getOfferId().compareTo(o2.getOfferId());//根据第一个参数小于、等于或大于第二个参数分别返回负整数、零或正整数
            }
        });
    }
}
